package trieMatch.util;

import java.io.File;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.List;

import trieMatch.Interfaces.ItemProcessorIF;
import trieMatch.Interfaces.ListProcessorIF;
import trieMatch.util.data.IO;

public class FileProcessor implements ListProcessorIF<String> {

	class ListProcessor implements ListProcessorIF<String> {
		protected ItemProcessorIF<String> itProcessor;
		PrintStream printStream;

		protected ListProcessor(final ItemProcessorIF<String> itemProcessor) {
			this(itemProcessor,null);
		}

		protected ListProcessor(final ItemProcessorIF<String> itemProcessor, final PrintStream printStream) {
			this.itProcessor = itemProcessor;
			this.printStream = printStream;
		}

		public void processQuerylist(final List<String> data) throws Exception {
			for (final String item : data) {
				itProcessor.processItem(item);
			}
		}

		public void setPrintStream(final PrintStream printStream) {
			this.printStream = printStream;
		}
	}

	private String[] typeList = ".dat".split(" +");
	protected ListProcessorIF<String> listProcessor;

	public FileProcessor(final ListProcessorIF<String> listProcessor) {
		this.listProcessor = listProcessor;
	}

	public FileProcessor(final ItemProcessorIF<String> itemProcessor) {
		this.listProcessor = new ListProcessor(itemProcessor);
	}

	public FileProcessor(final ItemProcessorIF<String> itemProcessor, final PrintStream printStream) {
		this.listProcessor = new ListProcessor(itemProcessor, printStream);
	}

	public FileProcessor(final ItemProcessorIF<String> itemProcessor, final String... typeList) {
		this(itemProcessor, null, typeList);
	}

	public FileProcessor(final ItemProcessorIF<String> itemProcessor, final PrintStream printStream, final String... typeList) {
		this(itemProcessor, printStream);
		this.typeList = new String[typeList.length];
		for (int i = 0; i < typeList.length; i++) {
			this.typeList[i] = typeList[i];
		}
	}

	public void setPrintStream(final PrintStream printStream) {
		// TODO Auto-generated method stub

	}

	void process(final File file) {
		if (file.isDirectory()) {
			final String[] files = file.list();
			Arrays.sort(files);
			for (final String element : files) {
				if (isDirectory(file, element) || isValidFiletype(element)) {
					process(new File(file, element));
				}
			}
		} else {
			try {
				processItems(file);
			} catch (final Exception e) {
				e.printStackTrace();
			}
		}
	}

	public List<String> process(final String[] names) {
		System.out.println();
		System.out.println("PROCESSING: " + Arrays.deepToString(names));
		final List<String> ans = null;
		for (final String filename : names) {
			process(new File(filename));
		}
		return ans;
	}

	boolean isDirectory(final File file, final String fn) {
		try {
			final File f = new File(file, fn);
			final boolean result = f.isDirectory();
			return result;
		} catch (final Exception e) {
			return false;
		}
	}

	boolean isValidFiletype(final String fn) {
		if (typeList == null || typeList.length == 0) {
			return true;
		}
		for (final String type : typeList) {
			if (fn.endsWith(type)) {
				return true;
			}
		}
		return false;
	}

	protected void processItems(final File f) throws Exception {
		final List<String> data = IO.readInput(f);
		listProcessor.processQuerylist(data);
	}

	public void processQuerylist(final List<String> queryList) throws Exception {
		listProcessor.processQuerylist(queryList);
	}

}
